/*
 * @Author: your name
 * @Date: 2021-02-19 17:02:52
 * @LastEditTime: 2021-02-19 17:03:08
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \utils\index.js
 */
/**
 * 基础工具类方法
 */

export const handler = e => {
  e.preventDefault();
};

/**
 * 是否可滑动
 * @param type
 * @param target
 */
export const touchMove = (type, target = document.getElementsByTagName('body')[0]) => {
  target[type]("touchmove", handler, {passive: false});
};

/**
 * 计算长度
 * @param data
 */
export const calcLength = data => {
  if (!data) {
    return false;
  }
  let length = data.replace(/[\u0391-\uFFE5]/g, '**').length;// 按照全角半角计算长度
  if (length > 12) {
    return true;
  }
  return false;
};

/**
  * 单位px转vw
  * @param {number | string} size - 像素尺寸
  * @param {number} width - 设计稿像素宽度（默认为1280px）
  * @param {number} unitPrecision - 单位精度（小数点后要保留的位数，默认为两位）
  * @returns {string} - 转换为vw单位的尺寸
  */
export const px2vw = (size, width = 1280, unitPrecision = 2) => {
  size = typeof size === 'string' ? +size.replace('px', '') : size;
  const vw = (size / width) * 100;
  return `${vw.toFixed(unitPrecision)}vw`;
};

/**
 * 滚动到顶部
 */
export const scrollToView = () => {
  document.body.addEventListener('focusout', () => {
    window.scrollTo(0, 0);
  });
};

/**
 * 金额转大写
 * @param n
 * @returns {string}
 */
export const moneyUppercase = (n) => {
  let fraction = ['角', '分'];
  let digit = [
    '零', '壹', '贰', '叁', '肆',
    '伍', '陆', '柒', '捌', '玖'
  ];
  let unit = [
    ['圆', '万', '亿'],
    ['', '拾', '佰', '仟']
  ];
  let head = n < 0 ? '欠' : '';
  n = Math.abs(n);
  let s = '';
  for (let i = 0; i < fraction.length; i++) {
    s += (digit[Math.floor(Math.floor(n * 1000 * 10 * Math.pow(10, i)) % (10 * 1000) / 1000)] + fraction[i]).replace(/零./, '');
  }
  s = s || '整';
  n = Math.floor(n);
  for (let i = 0; i < unit[0].length && n > 0; i++) {
    let p = '';
    for (let j = 0; j < unit[1].length && n > 0; j++) {
      p = digit[n % 10] + unit[1][j] + p;
      n = Math.floor(n / 10);
    }
    s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
  }
  return head + s.replace(/(零.)*零圆/, '圆').replace(/(零.)+/g, '零').replace(/^整$/, '零圆整');
};

/**
 * 数组去除重复数据
 */
export const distinct = (arr) => {
  let result = [];
  arr.forEach((v, i, arr) => {
    let bool = arr.indexOf(v, i + 1);
    if (bool === -1) {
      result.push(v);
    }
  });
  return result;
};

/**
 * 获取字符串的 储存长度
 * UCS-2编码(16进制) UTF-8 字节流(二进制)
 * 0000 - 007F       0xxxxxxx （1字节）
 * 0080 - 07FF       110xxxxx 10xxxxxx （2字节）
 * 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx （3字节）
 * @param val - 要计算的字符串
 * @returns {number} - 字节长度 单位 byte
 */
export const getStrLength = (val) => {
  var str = new String(val);
  var bytesCount = 0;
  for (var i = 0, n = str.length; i < n; i++) {
    var c = str.charCodeAt(i);
    if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
      bytesCount += 1;
    } else {
      bytesCount += 2;
    }
  }
  return bytesCount;
};

/**
 * 根据传入的距离转换成相对应的长度单位
 * get 100 - return 100米
 * get 1000 - return 1公里
 * 统一保留一个小数点
 * @param val - 距离长度 （米）
 * @returns {String} - 单位
 */
export const getDistanceMsg = (val) => {
  var _distant = +val;
  var _result = '';
  if (_distant > 0) {
    if (_distant < 1000) {
      _result = val + '米'
    } else {
      var kilometres = ((val / 1000).toFixed(1)).toString();
      if (+kilometres.split('.')[1] > 0) {
        _result = kilometres + '公里'
      } else {
        _result = kilometres.split('.')[0] + '公里'
      }
    }
  } else {
    _result = val;
  }
  return _result;
};

/**
 * 数值千分位格式化（从个位数起，每三位之间加一个逗号。例如“1,000”）
 * @param {number} num - 要进行格式化的数值
 * @returns {string} - 格式化后的字符串
 */
export const toThousands = num => {
  let result = '';
  num = (num || 0).toString();
  while (num.length > 3) {
    result = ',' + num.slice(-3) + result;
    num = num.slice(0, num.length - 3);
  }
  if (num) {
    result = num + result;
  }
  return result;
};

/**
 * 数值加上单位（万，亿）
 * 数值小于一万大于一千时，千位后面加上一个 逗号`,`；加上单位后数值部分每千位加上逗号`,`；大于1亿保留一位小数点
 * @param {number} num - 要进行格式化的数值  整数
 * @returns {object} - 返回值为对象 ps: {num: ‘1’, unit: '万'}
 *
 */
export const addUnitWithCount = num => {
  num = (num || 0).toString();
  let result = '';
  let unit = '';
  let length = num.length;
  if (num.includes('.')) {
    result = num
  } else if (length > 4) {
    let afterPointNum = ''; //小数点以及后面数据
    let pointNumStart = length - 1; //小数开始位置
    let pointNumber = 0;  //小数位数
    let cutNum = 0;
    if (length < 9) {
      //万级
      unit = '万';
      cutNum = 4;
    } else {
      //亿级
      unit = '亿';
      cutNum = 8;
    }
    switch (length) {
      case 5:
        //万 两个小数点
        pointNumber = 2;
        break;
      case 6:
        //十万 两个小数点
        pointNumber = 2;
        pointNumStart = pointNumStart - 1;
        break;
      case 7:
        //百万 一个小数点
        pointNumber = 1;
        pointNumStart = pointNumStart - 2;
        break;
      case 9:
        //亿 两个小数点
        pointNumber = 2;
        break;
      case 10:
        //十亿 两个小数点
        pointNumber = 2;
        pointNumStart = pointNumStart - 1;
        break;
      case 11:
        //百亿 一个小数点
        pointNumber = 1;
        pointNumStart = pointNumStart - 2;
        break;
    }
    if (pointNumber) {
      let secondPoint = pointNumber === 2 ? num.slice(length - (pointNumStart-1), length - (pointNumStart - 2)) : ''; //小数点后面的第二个数
      afterPointNum = '.' + num.slice(length - pointNumStart, length - (pointNumStart-1)) + secondPoint;
    }
    num = num.slice(0, length - cutNum);
    while (num.length > 3) {
      result = ',' + num.slice(-3) + result;
      num = num.slice(0, num.length - 3);
    }
    result = num + result + afterPointNum;
  } else if (length > 3) {
    result = num.slice(0, 1) + ',' + num.slice(-3);
  } else {
    result = num
  }
  return {
    num: result,
    unit: unit
  };
};

/**
 * 根据键名获取值，数组为[key:value]格式
 * @param arr  匹配数组
 * @param v 当前键名
 * @returns {{key: string, value: string}}
 */
export const getDicValue = (arr, v = '') => {
  let key = '', value = '';
  if (arr instanceof Array && (v || v === 0)) {
    arr.forEach(n => {
      for (let j in n) {
        if (j === v.toString()) {
          value = n[j];
          key = j;
        }
      }
    });
  }
  return {
    key: key,
    value: value
  }
};

/**
 * 去除最后的符号
 * @param data
 * @returns {*}
 */
export const removeComma = (data) => {
  const reg = /(,|，|\.|。|、|;|；|!|！|\?|？|~|～|@|#|¥|\$|%|&|\*|\(|\)|（|）|'|"|“|”|:|：|\\|\/|\^|\-|\=)$/;
  return data.replace(reg, '');
};

/**
 * string转boolean
 * @param data
 * @returns {boolean}
 */
export const stringToBoolean = (data) => {
  return (/^true$/i).test(data);
};

/**
 * 判断是否是空对象
 * @param data
 * @returns {boolean}
 */
export const isEmptyObj = (data) => {
  return data ? JSON.stringify(data) === '{}' : true;
};

/**
 * 转字符串类型
 * @param data
 * @returns {string}
 */
export const toString = (data) => {
  if (typeof data !== 'object' || data === null) {
    if (typeof data === 'boolean') {
      return data;
    }
    if (!data && data !== 0) {
      return '';
    }
    return data.toString();
  }
  let newObj = Array.isArray(data) ? [] : {};
  if (data) {
    for (let k in data) {
      if (data[k] && typeof data[k] === 'object') {
        newObj[k] = toString(data[k]);
      } else {
        newObj[k] = !data[k] && data[k] !== 0 ? '' : data[k].toString();
      }
    }
  }
  return newObj;
};

/**
 * 对象深拷贝
 * @param obj
 * @returns {*}
 */
export const deepCopy = (obj) => {
  // 根据obj的类型判断是新建一个数组还是对象
  let newObj = Array.isArray(obj) ? [] : {};
  // 判断传入的obj存在，且类型为对象
  if (obj && typeof obj === 'object') {
    for (let k in obj) {
      // 如果obj的子元素是对象，则进行递归操作
      if (obj[k] && typeof obj[k] === 'object') {
        newObj[k] = deepCopy(obj[k]);
      } else {
        // 如果obj的子元素不是对象，则直接赋值
        newObj[k] = obj[k];
      }
    }
  }
  return newObj;
};

/**
 * 判断是否为微信
 * @returns {boolean}
 */
export const isWeChat = () => {
  const ua = window.navigator.userAgent.toLowerCase();
  if (ua.match(/MicroMessenger/i) == 'micromessenger') {
    return true;
  } else {
    return false;
  }
};

/**
 * 格式化时间
 * @param data 时间戳
 * @param fmt  转换格式
 * @returns {*}
 */
export const formatDate = (data, fmt = 'yyyy-MM-dd') => {
  if (!data) {
    return '';
  }
  //苹果设备上面 需要将 - 转换成 / , / 在其他设备上面也适用
  let dateData = (data+'').includes('-') ? data.replace(/-/g, "/") : data;
  let date = new Date(dateData);
  if (date === null) {
    return "";
  }
  let o = {
    "M+": date.getMonth() + 1, //月份
    "d+": date.getDate(), //日
    "h+": date.getHours(), //小时
    "m+": date.getMinutes(), //分
    "s+": date.getSeconds(), //秒
    "c+": date.getMilliseconds(), //毫秒
  };
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  for (const k in o)
    if (new RegExp("(" + k + ")").test(fmt)) {
      const length = RegExp.$1.length;
      fmt = fmt.replace(RegExp.$1, (length == 1) ? (o[k]) : ((Array(length + 1).join('0') + o[k]).substr(("" + o[k]).length)));
    }
  return fmt;
};

/**
 * 将'-'替换为'/'
 * @param data
 * @returns {*}
 */
export const formatIOSData = (data) => {
  return /-/g.test(data) ? data.replace(/-/g, '/') : data;
};

/**
 * 清空对象的值
 * @param data
 */
export const clearObjData = (data) => {
  if (!isEmptyObj(data)) {
    for (let key in data) {
      data[key] = '';
    }
  }
};

/**
 * 根据身份证号获取年龄
 * @param idCode
 * @returns {*}
 */
export const getAge = (idCode) => {
  if (!idCode) {
    return '';
  }
  let idDate = idCode.substr(6, 8);
  let strBirthDate = `${idDate.substr(0, 4)}/${idDate.substr(4, 2)}/${idDate.substr(6, 2)}`; //时间字符串里，必须是“/”
  let birthDate = new Date(strBirthDate);
  let nowDate = new Date();
  if (birthDate instanceof Date && !isNaN(birthDate.getTime())) {
    let age = nowDate.getFullYear() - birthDate.getFullYear();
    //再考虑月、天的因素;.getMonth()获取的是从0开始的，这里进行比较，不需要加1
    if (nowDate.getMonth() < birthDate.getMonth() || (nowDate.getMonth() === birthDate.getMonth() && nowDate.getDate() < birthDate.getDate())) {
      age--;
    }
    return age;
  }
};

/**
 * 根据身份证号获取性别
 * @param idCode
 * @returns {string}
 */
export const getSex = (idCode) => {
  if (!idCode) {
    return '';
  }
  if (parseInt(idCode.substr(16, 1)) % 2 == 1) {
    return '1';//男
  } else {
    return '2';//女
  }
};

/**
 * 比较两个值（嵌套对象/数组/其他任意类型）是否相等
 * @param {any} origin - 要进行比较的任意类型值
 * @param {any} target - 要进行比较的任意类型值
 * @returns {boolean} - 比较结果
 */
export const compare = (origin, target) => {
  if (typeof target !== "object" || target === null) {
    // target不是对象/数组
    return origin === target; // 直接返回全等的比较结果
  }
  if (typeof origin !== "object" || origin === null) {
    // origin不是对象/数组
    return false; // 直接返回false
  }
  // 基于成员数多的对象/数组进行遍历
  const targetKeys = Object.keys(target);
  const originKeys = Object.keys(origin);
  const keys = targetKeys.length > originKeys.length ? targetKeys : originKeys;
  for (const key of keys) {
    // 遍历target的所有自身属性的key
    if (!compare(origin[key], target[key])) {
      // 递归比较key对应的value，
      // value不等，则两对象不等，结束循环，退出函数，返回false
      return false;
    }
  }
  // 遍历结束，所有value都深度比较相等，则两对象相等
  return true;
};

/**
 * 阿拉伯数字转中文
 * @param data
 * @returns {string}
 */
export const NumberUppercase = (data) => {
  let chnNumChar = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
  let chnUnitChar = ["", "十", "百", "千"];
  let strIns = '', chnStr = '', unitPos = 0, zero = true, copyData = data;
  while (data > 0) {
    let v = data % 10;
    if (v === 0) {
      if (!zero) {
        zero = true;
        chnStr = chnNumChar[v] + chnStr;
      }
    } else {
      zero = false;
      strIns = chnNumChar[v];
      strIns += chnUnitChar[unitPos];
      chnStr = strIns + chnStr;
    }
    unitPos++;
    data = Math.floor(data / 10);
  }
  if (copyData >= 10 && copyData < 20) {
    chnStr = chnStr.substr(1, chnStr.length);
  }
  return chnStr;
};

//选择列表转换 由 [{'1': 11}] 转换成 [{label: 111, value: '1'}]
export const transOption = (arr)=>{
  let newArr = [];
  arr.forEach(v =>{
    let firstKey = Object.keys(v)[0];
    newArr.push({
      label: v[firstKey],
      // key为纯数字时转换为Number类型
      value: /^\d+$/.test(firstKey) ? +firstKey : firstKey
    })
  });
  return newArr;
};

/**
 * 显示没有数据时的符号
 */
export const noDataToSymbol = (val)=>{
  return !!val ? val : '— —'
};

/**
 * 判断是否为ios系统
 */
export const isIOS = () => {
  return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
};
